package top.glkj.hms.service.impl;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import top.glkj.hms.dao.ActivityDao;
import top.glkj.hms.dao.OrderFormDao;
import top.glkj.hms.dao.UserDao;
import top.glkj.hms.dao.VipUserDao;
import top.glkj.hms.dto.IndexOffer;
import top.glkj.hms.entity.*;
import top.glkj.hms.service.IndexService;
import top.glkj.hms.service.UserService;
import top.glkj.hms.utils.Result;
import top.glkj.hms.utils.ResultFactory;
import top.glkj.hms.utils.StaticValue;
import top.glkj.hms.utils.Status;

import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author : xgl
 * @version : 0.0.1
 * @date :2020/12/9 23:44
 */
@Service
@Slf4j
public class IndexServiceImpl implements IndexService {
    private final UserService userService;
    private final OrderFormDao orderFormDao;
    private final ActivityDao activityDao;
    private final UserDao userDao;
    private final VipUserDao vipUserDao;

    @Autowired
    public IndexServiceImpl(UserService userService, OrderFormDao orderFormDao, ActivityDao activityDao, UserDao userDao, VipUserDao vipUserDao) {
        this.userService = userService;
        this.orderFormDao = orderFormDao;
        this.activityDao = activityDao;
        this.userDao = userDao;
        this.vipUserDao = vipUserDao;
    }

    /**
     * 根据用户存储信息获取菜单
     *
     * @param user 登录用户
     * @return 菜单
     */
    @Override
    public Result getMenu(User user) {
        Result one = userService.getOne(user.getId());
        if (ResultFactory.isSuccess(one)) {
            user = (User) one.getObject();
            Set<Resource> collect = user.getRoles().stream()
                    .filter(role -> role != StaticValue.NULL)
                    .map(Role::getPermissions)
                    .collect(Collectors.toSet())
                    .stream()
                    .filter(role -> !role.isEmpty())
                    .map(Set::iterator)
                    .collect(Collectors.toSet())
                    .stream()
                    .filter(role -> role != StaticValue.NULL)
                    .map(Iterator::next)
                    .collect(Collectors.toSet())
                    .stream()
                    .filter(role -> role != StaticValue.NULL)
                    .map(Permission::getResources)
                    .collect(Collectors.toSet())
                    .stream()
                    .filter(role -> role != StaticValue.NULL)
                    .map(Set::iterator)
                    .collect(Collectors.toSet())
                    .stream()
                    .filter(role -> role != StaticValue.NULL)
                    .map(Iterator::next)
                    .collect(Collectors.toSet());
            return ResultFactory.isSuccess(StaticValue.GET_DATA_SUCCESS, collect);
        } else {
            return one;
        }

    }

    @Override
    public Result getData() {
        IndexOffer offer = new IndexOffer();
        offer.setCountUser(userDao.count());
        offer.setCountVip(vipUserDao.count());
        Date start = new Date();
        Date end = new Date();
        start.setDate(start.getDate()-7);
        offer.setCountLogin(userDao.loginCount(start,end));
        offer.setNewAddUser(userDao.count((Specification<User>) (root, query, cb) -> cb.and(cb.between(root.get("createTime"),start,end))));
        offer.setNewAddOrder(orderFormDao.count((Specification<OrderForm>) (root, query, cb) -> cb.and(cb.between(root.get("createTime"),start,end))));
        offer.setNewAddVipUser(vipUserDao.count((Specification<VipUser>) (root, query, cb) -> cb.and(cb.between(root.get("createTime"),start,end))));
        offer.setCompletedOrder(orderFormDao.count(
                (Specification<OrderForm>) (root, query, cb) ->
                cb.and(cb.equal(root.get("status"), Status.Finnish),cb.between(root.get("createTime"),start,end))
        ));
        offer.setProgressOrder(orderFormDao.count(
                (Specification<OrderForm>) (root, query, cb) ->
                        cb.and(cb.notEqual(root.get("status"), Status.Finnish),
                                cb.notEqual(root.get("status"),Status.ToStay),
                                cb.between(root.get("createTime"),start,end))
        ));
        offer.setReservationOrder(orderFormDao.count(
                (Specification<OrderForm>) (root, query, cb) ->
                        cb.and(cb.equal(root.get("status"), Status.ToStay),cb.between(root.get("createTime"),start,end))
        ));
        Date date1=new Date(),date2 = new Date();
        HashMap<String,Long> hashMap = new HashMap<>();
        for (int i = 1; i <= 7; i++) {
            date1 = getWeek(date1.getDay(),i);
            date2.setDate(date1.getDate()+1);
            Date finalDate = date1;
            hashMap.put(getWeekChinese(i),orderFormDao.count((Specification<OrderForm>) (root, query, cb) ->
                    cb.between(root.get("createTime"), finalDate,date2)
                    ));
        }
        offer.setWeekOrder(hashMap);
        return ResultFactory.isSuccess(offer);
    }

    private Date getWeek(int week,int day){
        Date date = new Date();
        switch (week){
            case 0:
                date.setDate(date.getDate()-7+day);return date;
            case 1:
                date.setDate(date.getDate()-1+day);return date;
            case 2:
                date.setDate(date.getDate()-2+day);return date;
            case 3:
                date.setDate(date.getDate()-3+day);return date;
            case 4:
                date.setDate(date.getDate()-4+day);return date;
            case 5:
                date.setDate(date.getDate()-5+day);return date;
            case 6:
                date.setDate(date.getDate()-6+day);return date;
            default:  return date;
        }
    }
    private String getWeekChinese(int day){
        switch (day){
            case 1:return "星期一";
            case 2:return "星期二";
            case 3:return "星期三";
            case 4:return "星期四";
            case 5:return "星期五";
            case 6:return "星期六";
            case 7:return "星期日";
            default:return "星期"+day;
        }
    }
}
